﻿using SuperX.SuperSocket.Socket.Command;
using SuperSocket.ProtoBase;
using System;
using System.Collections.Generic;
using System.Text;

namespace SuperX.SuperSocket.Socket.Message
{
    public class MessagePackageInfo : PackageInfo<string, SocketMessage>
    {
        public MessagePackageInfo(string key, SocketMessage body) : base(key, body)
        {
        }
    }

    public class MessageClientReceiveFilter : FixedHeaderReceiveFilter<MessagePackageInfo>
    {
        public MessageClientReceiveFilter() : base(SocketMessage.FixHeaderLength)
        {
        }

        public override MessagePackageInfo ResolvePackage(IBufferStream bufferStream)
        {
            byte[] headerBytes = new byte[SocketMessage.FixHeaderLength];
            bufferStream.Read(headerBytes, 0, SocketMessage.FixHeaderLength);
            var len = BitConverter.ToInt32(headerBytes, 5);
            var dataLength = len / 256 + len % 256 + BitConverter.ToInt32(headerBytes, 9);

            byte[] bodyBuffer = new byte[dataLength];
            bufferStream.Read(bodyBuffer, 0, dataLength);

            SocketMessage message = new SocketMessage();
            if (headerBytes[0] != 67 || headerBytes[1] != 81)
            {
                message.Error = "Fix header error";
                message.IsError = true;
            }
            else
            {
                var headerLength = (int)(BitConverter.ToUInt32(headerBytes, 5) / 256);
                var cmdLength = (int)(BitConverter.ToUInt32(headerBytes, 5) % 256);
                var bodyLength = BitConverter.ToInt32(headerBytes, 9);
                message.Command = Encoding.UTF8.GetString(bodyBuffer.CloneRange(0, cmdLength));
                message.Header = Encoding.UTF8.GetString(bodyBuffer.CloneRange(cmdLength, headerLength));
                if (message.Command == "SendObjectWithHeaders")
                {
                    message.Headers = CommandTransfer.ConvertHeaders(message.Header);
                    message.Header = string.Empty;
                }
                message.Body = bodyBuffer.CloneRange(cmdLength + headerLength, bodyLength);
            }
            return new MessagePackageInfo(message.Command, message);
        }

        protected override int GetBodyLengthFromHeader(IBufferStream bufferStream, int length)
        {
            byte[] header = new byte[SocketMessage.FixHeaderLength];
            bufferStream.Read(header, 0, SocketMessage.FixHeaderLength);
            var len = BitConverter.ToInt32(header, 5);
            return len / 256 + len % 256 + BitConverter.ToInt32(header, 9);
        }
    }
}
